package com.suray.basic.wcs.node;

import com.suray.basic.wcs.node.bo.WCSNodeModuleBO;
import com.suray.basic.wcs.node.bo.WCSNodeModuleRouteBO;
import com.suray.basic.wcs.path.core.Node;
import com.suray.basic.wcs.path.core.Route;
import com.suray.basic.wcs.utils.LockNode;
import org.springframework.beans.BeanUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class WCSNodeModule {
    public static Map<String, WCSNodeModuleBO> wcsNodeModuleMapCache = new ConcurrentHashMap<>();
    public static Map<String, Node> lockTimeByNodeMapCache = new ConcurrentHashMap<>();

    // 增加节点经过者，计算预计加锁时间
    public static void addWcsNodeModuleMapCacheRouteBy(Integer id, Route route, Map<String, Node> nodeMap, int waitReleaseNodeSize) {
        for (int i = 0; i < route.getNodeList().size(); i++) {
            List<Node> nodeList = route.getNodeList();
            for (int j = 0; j < nodeList.size(); j++) {
                if (j >= waitReleaseNodeSize) {
                    lockTimeByNodeMapCache.put(id + nodeList.get(j).toString(), nodeList.get(j - waitReleaseNodeSize));
                }
                Node node = nodeList.get(j);
                WCSNodeModuleBO wcsNodeModuleBO = wcsNodeModuleMapCache.get(node.toString());
                Node nodeMapItem = nodeMap.get(node.toString());
                if (wcsNodeModuleBO == null) {
                    wcsNodeModuleBO = new WCSNodeModuleBO();
                    BeanUtils.copyProperties(node, wcsNodeModuleBO);
                    wcsNodeModuleMapCache.put(node.toString(), wcsNodeModuleBO);
                    WCSNodeModuleRouteBO wcsNodeModuleRouteBO = new WCSNodeModuleRouteBO();
                    wcsNodeModuleRouteBO.setKey(id);
                    wcsNodeModuleRouteBO.setLockTime(0);
                    wcsNodeModuleRouteBO.setRouteDirection(node.getDirection());
                    if (nodeMapItem != null) {
                        wcsNodeModuleRouteBO.setPassTime(nodeMapItem.passTime);
                        wcsNodeModuleRouteBO.setCurrentPassTime(nodeMapItem.currentNodePassTime);
                    } else {
                        wcsNodeModuleRouteBO.setPassTime(0);
                        wcsNodeModuleRouteBO.setCurrentPassTime(0);
                    }
                    wcsNodeModuleBO.addRouteBy(id.toString(), wcsNodeModuleRouteBO);
                } else {
                    WCSNodeModuleRouteBO wcsNodeModuleRouteBO = wcsNodeModuleBO.getRouteBy().get(id.toString());
                    if (wcsNodeModuleRouteBO != null) {
                        wcsNodeModuleRouteBO.setLockTime(0);
                    } else {
                        wcsNodeModuleRouteBO = new WCSNodeModuleRouteBO();
                        wcsNodeModuleRouteBO.setKey(id);
                        wcsNodeModuleRouteBO.setLockTime(0);
                        wcsNodeModuleRouteBO.setRouteDirection(node.getDirection());
                        if (nodeMapItem != null) {
                            wcsNodeModuleRouteBO.setPassTime(nodeMapItem.passTime);
                            wcsNodeModuleRouteBO.setCurrentPassTime(nodeMapItem.currentNodePassTime);
                        } else {
                            wcsNodeModuleRouteBO.setPassTime(0);
                            wcsNodeModuleRouteBO.setCurrentPassTime(0);
                        }
                        wcsNodeModuleBO.addRouteBy(id.toString(), wcsNodeModuleRouteBO);
                    }
                }
            }
        }
    }

    /**
     * 更新节点管理里锁定信息
     *
     * @param waitExecuteNodeList
     */
    public static void updateWcsNodeModuleMapCacheRouteBy(List<Node> waitExecuteNodeList, Integer id, Map<String, Node> nodeMap) {
        for (int j = 0; j < waitExecuteNodeList.size(); j++) {
            Node lockNode = lockTimeByNodeMapCache.get(id + waitExecuteNodeList.get(j).toString());
            int passTime = 0;
            if (lockNode != null) {
                Node nodeMapItem = nodeMap.get(lockNode.toString());
                if (nodeMapItem != null) {
                    passTime = nodeMapItem.passTime - nodeMapItem.currentNodePassTime;
                    if (passTime < 0) {
                        passTime = 0;
                    }
                }
            }
            Node node = waitExecuteNodeList.get(j);
            Node nodeMapItem = nodeMap.get(node.toString());
            WCSNodeModuleBO wcsNodeModuleBO = wcsNodeModuleMapCache.get(node.toString());
            if (wcsNodeModuleBO != null) {
                WCSNodeModuleRouteBO wcsNodeModuleRouteBO = wcsNodeModuleBO.getRouteBy().get(id.toString());
                if (wcsNodeModuleRouteBO != null) {
                    if (j == 0) {
                        wcsNodeModuleRouteBO.setLockTime(0);
                    } else {
                        wcsNodeModuleRouteBO.setLockTime(passTime);
                    }
                    if (nodeMapItem != null) {
                        wcsNodeModuleRouteBO.setPassTime(nodeMapItem.passTime);
                        wcsNodeModuleRouteBO.setCurrentPassTime(nodeMapItem.currentNodePassTime);
                    } else {
                        wcsNodeModuleRouteBO.setPassTime(0);
                        wcsNodeModuleRouteBO.setCurrentPassTime(0);
                    }
                    wcsNodeModuleBO.addRouteBy(id.toString(), wcsNodeModuleRouteBO);
                    if (passTime == 0) {
                        lockTimeByNodeMapCache.remove(id + waitExecuteNodeList.get(j).toString());
                    }
                }
            }
        }
    }

    public static void cleanWcsNodeModuleMapCacheRouteBy(Integer id, List<Node> nodeList, Node currentNode) {
        boolean flag = true;
        for (int j = 0; j < nodeList.size() && flag; j++) {
            Node node = nodeList.get(j);
            if (!node.equals(currentNode)) {
                WCSNodeModuleBO wcsNodeModuleBO = wcsNodeModuleMapCache.get(node.toString());
                if (wcsNodeModuleBO != null) {
                    wcsNodeModuleBO.removeRouteBy(id.toString());
                }
            } else {
                flag = false;
            }
        }
    }

    /**
     * 移除节点管理里路径使用信息
     *
     * @param nodeList
     */
    public static void cleanWcsNodeModuleMapCacheRouteBy(Integer id, List<Node> nodeList) {
        for (int i = 0; i < nodeList.size(); i++) {
            Node node = nodeList.get(i);
            WCSNodeModuleBO wcsNodeModuleBO = wcsNodeModuleMapCache.get(node.toString());
            if (wcsNodeModuleBO != null) {
                wcsNodeModuleBO.removeRouteBy(id.toString());
            }
        }
    }

    public static void cleanWcsNodeModuleMapCacheNodeBy(Node currentNode) {
        WCSNodeModuleBO wcsNodeModuleBO = wcsNodeModuleMapCache.get(currentNode.toString());
        if (wcsNodeModuleBO != null) {
            WCSNodeModuleRouteBO maxLockTimeWCSNodeModuleRouteBO = wcsNodeModuleBO.getMaxLockTimeWCSNodeModuleRouteBO();
            maxLockTimeWCSNodeModuleRouteBO.setLockTime(0);
            maxLockTimeWCSNodeModuleRouteBO.setPassTime(0);
            maxLockTimeWCSNodeModuleRouteBO.setCurrentPassTime(0);
        }
    }

    /**
     * 移除节点管理里路径使用信息
     *
     * @param id
     */
    public static void cleanWcsNodeModuleMapCacheRouteBy(Integer id) {
        for (Map.Entry<String, WCSNodeModuleBO> item : wcsNodeModuleMapCache.entrySet()) {
            WCSNodeModuleBO wcsNodeModuleBO = item.getValue();
            wcsNodeModuleBO.removeRouteBy(id.toString());
        }
    }

    /**
     * 更新节点管理里锁定信息
     *
     * @param nodeList
     */
    public static void updateWcsNodeModuleMapCacheLockBy(List<LockNode> nodeList, Integer id) {
        for (int i = 0; i < nodeList.size(); i++) {
            LockNode lockNode = nodeList.get(i);
            WCSNodeModuleBO wcsNodeModuleBO = wcsNodeModuleMapCache.get(lockNode.toString());
            if (wcsNodeModuleBO == null) {
                wcsNodeModuleBO = new WCSNodeModuleBO();
                BeanUtils.copyProperties(lockNode, wcsNodeModuleBO);
                wcsNodeModuleMapCache.put(lockNode.toString(), wcsNodeModuleBO);
            }
            wcsNodeModuleBO.setLockBy(lockNode.getLockedBy());
        }
    }

    /**
     * 移除节点管理里锁定信息
     *
     * @param nodeList
     */
    public static void removeWcsNodeModuleMapCacheLockBy(List<Node> nodeList, Integer id) {
        for (int i = 0; i < nodeList.size(); i++) {
            Node lockNode = nodeList.get(i);
            WCSNodeModuleBO wcsNodeModuleBO = wcsNodeModuleMapCache.get(lockNode.toString());
            if (wcsNodeModuleBO != null) {
                wcsNodeModuleBO.getRouteBy().remove(id.toString());
            }
        }
    }

    /**
     * 移除节点管理里锁定信息
     *
     * @param lockBy
     */
    public static void removeWcsNodeModuleMapCacheLockBy(Object lockBy) {
        for (Map.Entry<String, WCSNodeModuleBO> item : wcsNodeModuleMapCache.entrySet()) {
            WCSNodeModuleBO wcsNodeModuleBO = item.getValue();
//            for (Map.Entry<String,  WCSNodeModuleRouteBO> ite :  wcsNodeModuleBO.getRouteBy().entrySet()) {
//                WCSNodeModuleRouteBO  wcsNodeModuleRouteBO = ite.getValue();
//                if(wcsNodeModuleRouteBO.getTaskId().equals(lockBy)){
//                    wcsNodeModuleBO.getRouteBy().remove(lockBy);
//                }
//            }
            wcsNodeModuleBO.getRouteBy().remove(lockBy);
        }
    }

}
